import { ReplaceOptions, ReplaceResult, ReplaceResultsItem, QueryReplaceInfo } from '@type/replace';
import { escapeRegExp, escapeHTML } from '@e/methods/escape';
import { ImageReferenceType, ImageInfo } from '@type/main-windowObject';
import {
	getMarkdownImageReferenceRegExp,
	isInlineImageReferenceRegExp,
	matchInlineImageReference2PartsRegExp,
	matchTagImageReference2PartsRegExp,
	matchInlineImageReferencePathRegExp,
	matchTagImageReferencePathRegExp,
	matchInlineImageReference3PartsRegExp,
	matchTagImageReference3PartsRegExp,
} from '@e/utils/regexp';

/**
 * 替换图片引用路径
 * @param strict 是否为严格匹配
 */
export function replaceImageReferencePath(
	content: string,
	options: ReplaceOptions,
	flags?: string,
	strict: boolean = false
) {
	// 替换结果
	const result: ReplaceResult = {
		content,
		results: [],
	};

	options.forEach((option, i) => {
		const str = escapeRegExp(option.target); // 对目标字符串转义
		let substituted = option.substituted;

		const reg = getMarkdownImageReferenceRegExp(str, flags, strict);

		// 每次的替换结果
		const resultItem: ReplaceResultsItem = {
			...option,
			id: i,
			success: false,
			regexpString: reg.toString(),
		};

		// 匹配出所有的图片引用
		result.content = result.content.replace(reg, (match) => {
			let replaced: string;
			// 是否为行内图片引用
			const isInline = isInlineImageReferenceRegExp.test(match);

			// 若是直接替换则不操作
			if (!option.directReplace) {
				let matchs: RegExpMatchArray | null;

				// 匹配出图片引用的路径部分
				if (isInline) {
					matchs = match.match(matchInlineImageReferencePathRegExp);
				} else {
					matchs = match.match(matchTagImageReferencePathRegExp);
				}

				if (matchs && matchs[1]) {
					// 替换路径
					substituted = matchs[1].replace(option.target, option.substituted);
				}
			}

			// 替换图片引用
			if (isInline) {
				replaced = match.replace(matchInlineImageReference2PartsRegExp, `$1${substituted}$2`);
			} else {
				replaced = match.replace(matchTagImageReference2PartsRegExp, `$1${substituted}$2`);
			}

			// 根据替换前后是否一致判断是否替换成功
			if (replaced !== match) {
				resultItem.success = true;
			}

			return replaced;
		});

		result.results.push(resultItem);
	});

	return result;
}

/**
 * 查询替换图片路径信息
 */
export function queryReplaceImageReferencePath(
	content: string,
	options: ReplaceOptions,
	imageInfo: ImageInfo[],
	neededType: ImageReferenceType[] = ['absolute', 'relative']
) {
	const results: QueryReplaceInfo[] = [];

	options.forEach((option) => {
		const str = escapeRegExp(option.target); // 对目标字符串转义

		// 匹配出所有的图片引用
		const matchs = content.match(getMarkdownImageReferenceRegExp(str));

		if (matchs) {
			matchs.forEach((match) => {
				// 是否为行内图片引用
				const isInline = isInlineImageReferenceRegExp.test(match);
				let matchs2: RegExpMatchArray | null;

				// 匹配出图片引用的三部分
				if (isInline) {
					matchs2 = match.match(matchInlineImageReference3PartsRegExp);
				} else {
					matchs2 = match.match(matchTagImageReference3PartsRegExp);
				}

				if (matchs2) {
					// 判断是否为需要的类型
					const isNeeded = imageInfo.some((t) => {
						// @ts-ignore
						return t.target === matchs2[2] && neededType.includes(t.type);
					});

					if (isNeeded) {
						const reg = new RegExp(str);

						// 生成新旧的html代码
						const _new = matchs2[2].replace(reg, () => {
							return `<span class="mark">${option.substituted}</span>`;
						});
						const _old = matchs2[2].replace(reg, (match) => {
							return `<span class="mark">${match}</span>`;
						});

						// 添加结果
						results.push({
							// 转义拼接
							new: escapeHTML(matchs2[1]) + _new + escapeHTML(matchs2[3]),
							old: escapeHTML(matchs2[1]) + _old + escapeHTML(matchs2[3]),
							target: matchs2[2],
							substituted: matchs2[2].replace(reg, option.substituted),
						});
					}
				}
			});
		}
	});

	return results;
}
